﻿/*
 * IO.h
 *
 */
#ifndef __GDK_IO_H__
#define __GDK_IO_H__

#include <gdk/core/Types.h>
#include <gdk/core/Unknown.h>
#include <gdk/core/Mutex.h>
#include <gdk/core/SharedPtr.h>


namespace gdk
{



	class GDK_CORE_EXPORT Input : virtual public Unknown
	{
		DECLARE_CLASS_HANDLE(Input)

	public:
		virtual ssize_t available(void) const = 0;
		virtual ssize_t peek(void*, ssize_t) const = 0;
		virtual ssize_t read(void*, ssize_t) = 0;
	};


	class GDK_CORE_EXPORT Output : virtual public Unknown
	{
		DECLARE_CLASS_HANDLE(Output)

	public:
		virtual ssize_t write(const void*, ssize_t) = 0;
	};


	class GDK_CORE_EXPORT IO : public Input, public Output
	{
		DECLARE_CLASS_HANDLE(IO)
	};


	class GDK_CORE_EXPORT Pipe : public IO
	{
		DECLARE_CLASS_HANDLE(Pipe)
		DECLARE_CLASS_INSTANCE2(Pipe, Input*, Output*)

		Input::Handle	_in;
		Output::Handle	_out;

	private:
		Pipe(Input* in, Output* out);

	public:
		virtual ssize_t available(void) const;
		virtual ssize_t peek(void *buf, ssize_t size) const;
		virtual ssize_t read(void *buf, ssize_t size);
		virtual ssize_t write(const void *data, ssize_t size);
	};


	class GDK_CORE_EXPORT MutexPipe : public IO
	{
		DECLARE_CLASS_HANDLE(MutexPipe)
		DECLARE_CLASS_INSTANCE4(MutexPipe, Input*, const SharedPtr<Mutex>&, Output*, const SharedPtr<Mutex>&)

	private:
		Input::Handle		_in;
		SharedPtr<Mutex> 	_mutex_in;

		Output::Handle		_out;
		SharedPtr<Mutex> 	_mutex_out;

	private:
		MutexPipe(Input* in, const SharedPtr<Mutex>& mutex_in, Output* out, const SharedPtr<Mutex>& mutex_out);

	public:
		virtual ssize_t available(void) const;
		virtual ssize_t peek(void *buf, ssize_t size) const;
		virtual ssize_t read(void *buf, ssize_t size);
		virtual ssize_t write(const void *data, ssize_t size);
	};



}//namespace gdk



#endif /*__GDK_IO_H__*/
